// Token管理工具
import { refreshToken } from '@/api/user'
import router from '@/router'

class TokenManager {
  constructor() {
    this.tokenCheckInterval = null
    this.lastActivityTime = Date.now()
    
    // 配置参数（与后端保持一致）
    this.ACTIVITY_TIMEOUT = 30 * 60 * 1000 // 30分钟无操作超时
    this.CHECK_INTERVAL = 5 * 60 * 1000 // 每5分钟检查一次
    this.REFRESH_THRESHOLD = 5 * 60 * 1000 // 剩余5分钟时刷新token
    
    this.initActivityMonitoring()
  }

  // 初始化活动监控
  initActivityMonitoring() {
    const events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click']
    events.forEach(event => {
      document.addEventListener(event, this.updateActivity.bind(this), true)
    })
  }

  // 更新最后活动时间
  updateActivity() {
    this.lastActivityTime = Date.now()
  }

  // 开始token检查
  startTokenCheck() {
    if (this.tokenCheckInterval) {
      clearInterval(this.tokenCheckInterval)
    }

    this.tokenCheckInterval = setInterval(() => {
      this.checkTokenStatus()
    }, this.CHECK_INTERVAL)

    // 立即执行一次检查
    this.checkTokenStatus()
  }

  // 停止token检查
  stopTokenCheck() {
    if (this.tokenCheckInterval) {
      clearInterval(this.tokenCheckInterval)
      this.tokenCheckInterval = null
    }
  }

  // 检查token状态
  async checkTokenStatus() {
    const token = localStorage.getItem('token')
    if (!token) {
      this.handleTokenExpired()
      return
    }

    try {
      // 检查用户活动超时
      const timeSinceLastActivity = Date.now() - this.lastActivityTime
      if (timeSinceLastActivity > this.ACTIVITY_TIMEOUT) {
        this.handleTokenExpired()
        return
      }

      // 检查token是否需要刷新
      const tokenPayload = this.parseTokenPayload(token)
      if (tokenPayload) {
        const timeToExpire = tokenPayload.exp * 1000 - Date.now()
        if (timeToExpire < this.REFRESH_THRESHOLD && timeToExpire > 0) {
          await this.attemptTokenRefresh()
        }
      }
    } catch (error) {
      console.error('检查token状态时出错:', error)
      this.handleTokenExpired()
    }
  }

  // 解析token载荷
  parseTokenPayload(token) {
    // 验证 token 是否存在且格式正确
    if (!token || typeof token !== 'string' || token.trim() === '') {
      return null
    }
    
    // 验证 JWT 格式（必须包含两个点）
    const parts = token.split('.')
    if (parts.length !== 3) {
      return null
    }
    
    try {
      const base64Url = parts[1]
      const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
      const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
      }).join(''))
      return JSON.parse(jsonPayload)
    } catch (error) {
      console.error('解析token失败:', error)
      return null
    }
  }

  // 尝试刷新token
  async attemptTokenRefresh() {
    try {
      const response = await refreshToken()
      // 响应拦截器已自动提取 ApiResponse.data 字段
      if (response && response.token) {
        const newToken = response.token
        localStorage.setItem('token', newToken)
        this.updateActivity()
        return true
      }
    } catch (error) {
      console.error('刷新token失败:', error)
      this.handleTokenExpired()
      return false
    }
  }

  // 处理token过期
  handleTokenExpired() {
    this.stopTokenCheck()
    
    // 清除所有相关的本地存储
    localStorage.removeItem('token')
    localStorage.removeItem('userId')
    localStorage.removeItem('username')
    localStorage.removeItem('name')
    localStorage.removeItem('userRoles')
    localStorage.removeItem('department')
    
    // 通知用户store清除状态
    try {
      import('@/stores/user').then(({ useUserStore }) => {
        const userStore = useUserStore()
        userStore.logout()
      })
    } catch (error) {
      // 忽略通知错误
    }
    
    if (router.currentRoute.value.path !== '/login') {
      router.push('/login')
    }
  }
  
  // 处理会话过期（由外部调用，如403错误时）
  handleSessionExpired() {
    this.handleTokenExpired()
  }

  // 用户登录时调用
  onLogin() {
    this.updateActivity()
    this.startTokenCheck()
  }

  // 用户登出时调用
  onLogout() {
    this.stopTokenCheck()
  }
}

const tokenManager = new TokenManager()
export default tokenManager